package com.dajie.pt.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
//import org.apache.tools.zip.ZipEntry;
//import org.apache.tools.zip.ZipOutputStream;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.dajie.pt.model.InvitationApply;

/**
 * file upload download
 * 
 * @author panbing.wu
 * 
 */
public class FileOperateUtil
{
	private static final String REALNAME = "realName";
	private static final String STORENAME = "storeName";
	private static final String SIZE = "size";
	private static final String SUFFIX = "suffix";
	private static final String CONTENTTYPE = "contentType";
	private static final String CREATETIME = "createTime";
	private static final String UPLOADDIR = "/uploadDir/";
	private static final String Linux_FILEDIR = "/ROOT/www/uploadDir/";

	public static String getUploadDir(HttpServletRequest request)
	{
		if (new File(Linux_FILEDIR).exists())
		{
			return Linux_FILEDIR;
		} else
		{
			return getFilePath(request);
		}
	}

	public static String getFilePath(HttpServletRequest request)
	{
		return request.getSession().getServletContext().getRealPath("/")
				+ FileOperateUtil.UPLOADDIR;
	}

	/**
	 * rename file
	 * 
	 * @param name
	 * @return
	 */
	private static String rename(String name)
	{

		Long now = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
		Long random = (long) (Math.random() * now);
		String fileName = now + "" + random;

		if (name.indexOf('.') != -1)
		{
			fileName += name.substring(name.lastIndexOf('.'));
		}

		return fileName;
	}

	/**
	 * zip
	 * 
	 * @param name
	 * @return
	 */
	private static String zipName(String name)
	{
		String prefix = "";
		if (name.indexOf('.') != -1)
		{
			prefix = name.substring(0, name.lastIndexOf('.'));
		} else
		{
			prefix = name;
		}
		return prefix + ".zip";
	}

	/**
	 * upload file
	 * 
	 * @param request
	 * @param params
	 * @param values
	 * @return
	 * @throws Exception
	 */
	public static List<Map<String, Object>> upload(HttpServletRequest request, String[] params,
			Map<String, Object[]> values) throws Exception
	{
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();

		MultipartHttpServletRequest mRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = mRequest.getFileMap();

		String uploadDir = request.getSession().getServletContext().getRealPath("/")
				+ FileOperateUtil.UPLOADDIR;
		File file = new File(uploadDir);

		if (!file.exists())
		{
			file.mkdir();
		}

		String fileName = null;
		int i = 0;
		for (Iterator<Map.Entry<String, MultipartFile>> it = fileMap.entrySet().iterator(); it
				.hasNext(); i++)
		{

			Map.Entry<String, MultipartFile> entry = it.next();
			MultipartFile mFile = entry.getValue();

			fileName = mFile.getOriginalFilename();

			String storeName = rename(fileName);

			String noZipName = uploadDir + storeName;
			String zipName = zipName(noZipName);

			// 上传成为压缩文件
			ZipOutputStream outputStream = new ZipOutputStream(new BufferedOutputStream(
					new FileOutputStream(zipName)));
			outputStream.putNextEntry(new ZipEntry(fileName));
			outputStream.setEncoding("GBK");

			FileCopyUtils.copy(mFile.getInputStream(), outputStream);

			Map<String, Object> map = new HashMap<String, Object>();
			// 固定参数值对
			map.put(FileOperateUtil.REALNAME, zipName(fileName));
			map.put(FileOperateUtil.STORENAME, zipName(storeName));
			map.put(FileOperateUtil.SIZE, new File(zipName).length());
			map.put(FileOperateUtil.SUFFIX, "zip");
			map.put(FileOperateUtil.CONTENTTYPE, "application/octet-stream");
			map.put(FileOperateUtil.CREATETIME, new Date());

			// 自定义参数值对
			if (params != null && params.length > 0)
			{
				for (String param : params)
				{
					map.put(param, values.get(param)[i]);
				}
			}

			result.add(map);
		}
		return result;
	}

	public static String upload(HttpServletRequest request, InvitationApply ia) throws Exception
	{

		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file");

		// 获得文件名：
		String realFileName = file.getOriginalFilename();
		// 获取路径
		// String ctxPath =
		// request.getSession().getServletContext().getRealPath("/") +
		// UPLOADDIR;
		String ctxPath = FileOperateUtil.getUploadDir(multipartRequest);
		// 创建文件
		File dirPath = new File(ctxPath);
		if (!dirPath.exists())
		{
			dirPath.mkdir();
		}
		File uploadFile = new File(ctxPath + ia.getBasicInfo().getName()
				+ realFileName.substring(realFileName.lastIndexOf('.')));
		FileCopyUtils.copy(file.getBytes(), uploadFile);
		return ctxPath + ia.getBasicInfo().getName()
				+ realFileName.substring(realFileName.lastIndexOf('.'));
	}

	/**
	 * download
	 * 
	 * @param request
	 * @param response
	 * @param downLoadPath
	 * @param contentType
	 * @param realName
	 * @throws Exception
	 */
	public static void download(HttpServletRequest request, HttpServletResponse response,
			String downLoadPath, String contentType, String realName) throws Exception
	{
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		downLoadPath = downLoadPath.startsWith("local") ? downLoadPath.split(":")[1] : downLoadPath;
		long fileLength = new File(downLoadPath).length();

		response.setContentType(contentType);
		response.setHeader("Content-disposition",
				"attachment; filename=" + new String(realName.getBytes("utf-8"), "ISO8859-1"));
		response.setHeader("Content-Length", String.valueOf(fileLength));

		bis = new BufferedInputStream(new FileInputStream(downLoadPath));
		bos = new BufferedOutputStream(response.getOutputStream());
		byte[] buff = new byte[4096];
		int bytesRead;
		while (-1 != (bytesRead = bis.read(buff, 0, buff.length)))
		{
			bos.write(buff, 0, bytesRead);
		}
		bis.close();
		bos.close();
	}

	static final int BUFFER = 4096;

	public static void zip(String path, String toFile) throws Exception
	{
		BufferedInputStream origin = null;
		FileOutputStream dest = new FileOutputStream(toFile);
		ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
		out.setEncoding("GBK");
		byte data[] = new byte[BUFFER];
		File f = new File(path);
		File files[] = f.listFiles();
		for (int i = 0; i < files.length; i++)
		{
			FileInputStream fi = new FileInputStream(files[i]);
			origin = new BufferedInputStream(fi, BUFFER);
			ZipEntry entry = new ZipEntry(files[i].getName());
			out.putNextEntry(entry);
			int count;
			while ((count = origin.read(data, 0, BUFFER)) != -1)
			{
				out.write(data, 0, count);
			}
			origin.close();
		}
		out.close();
	}
}